/**
 * \file mem.h
 * \brief Memory management for ripescript. You should not use any other
 * functions but these.
 **/

#ifndef R_MEM_H
#define R_MEM_H

#include <stdlib.h>
#include <gc/gc.h>

/**
 * Current implementation only uses the Boehm GC (libgc). Future applications
 * will allow the programmer to compile the interpreter using their own, host
 * garbage collector.
 **/

/**
 * \brief Returns a pointer to the block following the given block pointed to.
 * It furthermore casts the given pointer to an arbitrary type. This is
 * normally used in conjuction with the Chunk data structure.
 **/
#define r_mem_after(p, t) ((t) ((p) + 1))

/**
 * \brief Allocates a certain number of bytes on the stack. It is implied that
 * these bytes will be deallocated after the function returns.
 **/
#define r_mem_alloca(size) alloca(size)

/**
 * \brief Frees a memory block. It may not actually do anything. Should only
 * be used for "large" objects.
 **/
#define r_mem_free(ptr) GC_FREE(ptr)

/**
 * \brief Allocates a certain number of bytes on the heap. These may contain
 * pointers to other blocks. This function is also guaranteed to zero the
 * memory pointed to.
 **/
#define r_mem_malloc(size) GC_MALLOC(size)

/**
 * \brief allocates a number of bytes on the heap. However there should be no
 * pointers to other blocks in this block. Also, this function may not zero
 * the memory block it returns.
 **/
#define r_mem_malloc_a(size) GC_MALLOC_ATOMIC(size)

/**
 * \brief Acts just like realloc(). It may or may not zero memory, depending
 * on whether r_malloc() or r_malloc_a() were called when initially creating
 * the block.
 **/
#define r_mem_realloc(ptr,size) GC_REALLOC(ptr, size)

#endif /* R_MEM_H */
